// GoogleTileSystem.js

const TileSystem = require('./TileSystem');
const turf = require('@turf/turf');

class GoogleTileSystem extends TileSystem {
    constructor(app) {
        super();
        this.app = app;
        this.tileSize = 256; // 每个切片的像素大小
        this.earthCircumference = 40075016.686; // 地球周长（米）
    }

    /**
     * 将度数转换为弧度
     * @param {Number} deg
     * @returns {Number}
     */
    toRadians(deg) {
        return deg * (Math.PI / 180);
    }

    /**
     * 根据纬度和缩放级别计算每像素的地面距离
     * @param {Number} lat - 纬度
     * @param {Number} zoom - 缩放级别
     * @returns {Number} - 米/像素
     */
    getMetersPerPixel(lat, zoom) {
        return (this.earthCircumference * Math.cos(this.toRadians(lat))) / (this.tileSize * Math.pow(2, zoom));
    }

    /**
     * 将经纬度转换为切片坐标
     * @param {Number} lat
     * @param {Number} lng
     * @param {Number} zoom
     * @returns {Object} - { x, y }
     */
    latLngToTile(lat, lng, zoom) {
        const scale = 1 << zoom;
        const x = ((lng + 180) / 360) * scale;
        const y = ((1 - Math.log(Math.tan(this.toRadians(lat)) + 1 / Math.cos(this.toRadians(lat))) / Math.PI) / 2) * scale;
        return { x: Math.floor(x), y: Math.floor(y) };
    }

    /**
     * 获取切片的地理范围
     * @param {Number} tileX - 切片X坐标
     * @param {Number} tileY - 切片Y坐标
     * @param {Number} zoom - 缩放级别
     * @returns {Object} - { nw: { lat, lng }, se: { lat, lng } }
     */
    getTileBounds(tileX, tileY, zoom) {
        const scale = 1 << zoom;

        // 计算东经和西经
        const lng1 = (tileX / scale) * 360 - 180;
        const lng2 = ((tileX + 1) / scale) * 360 - 180;

        // 计算北纬和南纬
        const n = Math.PI - (2 * Math.PI * tileY) / scale;
        const nwLat = (180 / Math.PI) * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));

        const nNext = Math.PI - (2 * Math.PI * (tileY + 1)) / scale;
        const seLat = (180 / Math.PI) * Math.atan(0.5 * (Math.exp(nNext) - Math.exp(-nNext)));

        return {
            nw: { lat: nwLat, lng: lng1 },
            se: { lat: seLat, lng: lng2 }
        };
    }

    /**
     * 计算覆盖的切片范围
     * @param {Number} centerLat - 截图中心纬度
     * @param {Number} centerLng - 截图中心经度
     * @param {Number} zoom - 缩放级别
     * @param {Number} imageWidth - 图像宽度（像素）
     * @param {Number} imageHeight - 图像高度（像素）
     * @param {Number} scale - 每像素的地面距离（米/像素）
     * @returns {Object} - { minX, maxX, minY, maxY }
     */
    calculateTileCoverage(centerLat, centerLng, zoom, imageWidth, imageHeight, scale) {
        const groundWidth = imageWidth * scale; // 米
        const groundHeight = imageHeight * scale; // 米

        const center = turf.point([centerLng, centerLat]);

        // 使用 turf.js 计算四个方向的边界点
        const north = turf.destination(center, groundHeight / 2000, 0, { units: 'kilometers' }); // 北
        const east = turf.destination(center, groundWidth / 2000, 90, { units: 'kilometers' }); // 东
        const south = turf.destination(center, groundHeight / 2000, 180, { units: 'kilometers' }); // 南
        const west = turf.destination(center, groundWidth / 2000, 270, { units: 'kilometers' }); // 西

        // 计算东北和西南角的实际覆盖范围
        const nePoint = turf.destination(north, groundWidth / 2000, 90, { units: 'kilometers' }).geometry.coordinates; // 东北
        const swPoint = turf.destination(south, groundWidth / 2000, 270, { units: 'kilometers' }).geometry.coordinates; // 西南

        // 将地理坐标转换为切片坐标
        const topTile = this.latLngToTile(nePoint[1], nePoint[0], zoom);
        const bottomTile = this.latLngToTile(swPoint[1], swPoint[0], zoom);

        // 将纬度方向计算为 minY 和 maxY，经度方向为 minX 和 maxX
        const leftTile = this.latLngToTile(centerLat, west.geometry.coordinates[0], zoom);
        const rightTile = this.latLngToTile(centerLat, east.geometry.coordinates[0], zoom);

        const tileRange = {
            minX: Math.min(leftTile.x, rightTile.x),
            maxX: Math.max(leftTile.x, rightTile.x),
            minY: Math.min(topTile.y, bottomTile.y),
            maxY: Math.max(topTile.y, bottomTile.y)
        };

        // 打印调试信息（可选）
        // console.log(`北边界点: [${north.geometry.coordinates}]`);
        // console.log(`东边界点: [${east.geometry.coordinates}]`);
        // console.log(`南边界点: [${south.geometry.coordinates}]`);
        // console.log(`西边界点: [${west.geometry.coordinates}]`);
        // console.log(`东北点: [${nePoint}]`);
        // console.log(`西南点: [${swPoint}]`);
        // console.log(`切片范围: X=${tileRange.minX} - ${tileRange.maxX}, Y=${tileRange.minY} - ${tileRange.maxY}`);

        return tileRange;
    }
}

module.exports = GoogleTileSystem;
